home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
loading
/
simplify_symtab.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-04-03
|
8KB
|
308 lines
/* begincopyright
Copyright (c) 1988 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
PCR Coordinator
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA
endcopyright */
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <stdio.h>
#include <a.out.h>
#include <errno.h>
#ifdef sparc
#define r_symbolnum r_index
#define relocation_info reloc_info_sparc
#endif
#define CLEAN(var) {if (var) {free(var); var = 0;}}
static int file_length;/* length of input file in bytes */
static FILE *file; /* input file */
struct exec header;
struct nlist *symtab;
caddr_t stringtab;
int num_symbols;
long string_len;
unsigned long num_reloc_data_items, num_reloc_text_items;
struct relocation_info *data_reloctab, *text_reloctab;/* relocation table */
unsigned long num_reloc_data_items_kept, num_reloc_text_items_kept;
#define INCN 60000
static int maxn = 0;
static int nextn = 0;
static int *saven = 0;
#define INCSTRX 60000*8
static int maxstrx = 0;
static int nextstrx = sizeof(int);
static caddr_t newstringtab = 0;
char *current_file;
compare_n(a, b)
int *a, *b;
{
return(*a - *b);
}
/*
* Main program for 'simplify_symtab'.
*/
main(argc, argv)
char **argv;
{
/* process arguments */
if (argc < 2) {
printf("Usage: %s filename.\n\tRemoves any dbx type symbols (those with stabs bits on.)~~the stab ", argv[0]);
exit(1);
};
for (; --argc > 0;) {
simplify_file(*++argv);
}
exit(0);
}
simplify_file(onefilename)
char *onefilename;
{
int i, n_i;
caddr_t cp;
printf("Simplifying %s.\n", onefilename);
current_file = onefilename; /* for error messages */
/*
* Initialize.
*/
maxn = 0;
nextn = 0;
CLEAN(saven);
CLEAN(symtab);
CLEAN(data_reloctab);
CLEAN(text_reloctab);
CLEAN(stringtab);
maxstrx = 0;
nextstrx = sizeof(int);
CLEAN(newstringtab);
/*
* Open the file: don't return if unopened.
*/
open_file(onefilename);
/*
* Look for symbols without nstab bits set--remember them.
* Remember the strings associated with the remembered symbols.
*/
for(i=0; i < num_symbols; i++ ) {
if ( ! (symtab[i].n_type & N_STAB)) {
remember_n(i);
cp = symtab[i].n_un.n_strx + stringtab;
symtab[i].n_un.n_strx = nextstrx;
remember_string(cp);
} else {
i = i; /* someplace to put a breakpoint */
}
}
/*
* Start point for writing new file information.
*/
fseek(file, N_TRELOFF(header), 0);
/*
* Write out text relocation information, adjusted to new symbol locations.
*/
num_reloc_text_items_kept = 0;
for (i=0; i < num_reloc_text_items; i++) {
if (text_reloctab[i].r_extern && (n_i = n_p(text_reloctab[i].r_symbolnum)) == -1) {
i = i; /* a place to put breakpoints */
} else {
if (text_reloctab[i].r_extern) {
text_reloctab[i].r_symbolnum = n_i;
}
fwrite(&text_reloctab[i], sizeof(struct relocation_info), 1, file);
num_reloc_text_items_kept += 1;
}
}
/*
* Write out data relocation information that points to saved symbols only.
*/
num_reloc_data_items_kept = 0;
for (i=0; i < num_reloc_data_items; i++) {
if (data_reloctab[i].r_extern && (n_i = n_p(data_reloctab[i].r_symbolnum)) == -1) {
i = i; /* a place to put breakpoints */
} else {
if (data_reloctab[i].r_extern) {
data_reloctab[i].r_symbolnum = n_i;
}
fwrite(&data_reloctab[i], sizeof(struct relocation_info), 1, file);
num_reloc_data_items_kept += 1;
}
}
/*
* Write out symbols that did not have nstabs bit set.
* by copying them in place on top of other symbols.
*/
for(i=0; i < nextn; i++ ) {
fwrite(&symtab[saven[i]], sizeof(struct nlist), 1, file);
}
/*
* Write out the same old stringtab (now in a new place in the file).
* fwrite(stringtab, string_len, 1, file);
*/
/*
* Write new string table
*/
*(int *)newstringtab = nextstrx;
fwrite(newstringtab, nextstrx, 1, file);
/*
* Update the header, and write it out.
*/
header.a_syms = sizeof(struct nlist)*nextn;
header.a_drsize = sizeof(struct relocation_info)*num_reloc_data_items_kept;
header.a_trsize = sizeof(struct relocation_info)*num_reloc_text_items_kept;
fseek(file, (long)0, 0);
fwrite(&header, sizeof(struct exec), 1, file);
fflush(file);
i = file_length - (num_symbols-nextn)*sizeof(struct nlist);
i -= (num_reloc_data_items - num_reloc_data_items_kept +
num_reloc_text_items - num_reloc_text_items_kept) * sizeof(struct relocation_info);
i -= string_len - nextstrx;
ftruncate(fileno(file), i);
/* done with this file */
fclose(file);
}
open_file(filename)
char *filename;
{
struct stat the_stat_buffer;
/*
* Open the file: don't return if unopened.
*/
if ((file = fopen(filename, "r+")) == NULL) {
char temp[128];
sprintf(temp, "Cannot open file '%s'.", filename);
error(temp); /* never returns */
}
/* get the file size */
fstat(fileno(file), &the_stat_buffer);
file_length = the_stat_buffer.st_size;
fseek(file, (long)0, 0);
fread (&header, sizeof(struct exec), 1, file);
if (N_BADMAG(header)) {
error("Bad magic number."); /* never returns */
}
num_reloc_text_items = (header.a_trsize / sizeof (struct relocation_info));
num_reloc_data_items = (header.a_drsize / sizeof (struct relocation_info));
if (num_reloc_text_items > 0) {
text_reloctab = (struct relocation_info *)malloc(sizeof(struct relocation_info)*num_reloc_text_items);
fseek(file, N_TRELOFF(header), 0);
fread (text_reloctab, sizeof (struct relocation_info), num_reloc_text_items, file);
}
if (num_reloc_data_items > 0) {
data_reloctab = (struct relocation_info *)malloc(sizeof(struct relocation_info)*num_reloc_data_items);
fseek(file, N_DRELOFF(header), 0);
fread (data_reloctab, sizeof (struct relocation_info), num_reloc_data_items, file);
}
/*
* Read in the symbol table
*/
num_symbols = header.a_syms / (sizeof (struct nlist));
if (num_symbols <= 0) {
error("No symbol table."); /* never returns */
}
symtab= (struct nlist *) malloc (header.a_syms);
fseek(file, N_SYMOFF(header), 0);
fread (symtab, sizeof (struct nlist), num_symbols, file);
/*
* Read in the string table
*/
{
string_len = (file_length - N_STROFF(header));
if (string_len <= 0) {
error("No string table."); /* never returns */
}
stringtab = (caddr_t) malloc (string_len);
fseek(file, N_STROFF(header), 0);
fread (stringtab, 1, string_len, file);
}
}
error(s)
char *s;
{
printf("simplify_symtab error: %s, in file '%s'\n", s, current_file);
exit(1);
}
remember_n(n)
int n;
{
if (nextn >= maxn) {
/* need more storage */
maxn += INCN;
if (saven) {
saven = (int *)realloc(saven, maxn*sizeof(int));
} else {
saven = (int *)malloc(maxn*sizeof(int));
}
}
saven[nextn++] = n;
}
n_p(n)
int n;
{
int *retval;
retval = (int *)bsearch(&n, saven, nextn, sizeof(int), compare_n);
if (retval == 0) {
return -1;
} else {
return ((long)retval - (long)saven)/sizeof(int);
}
}
remember_string(cp)
caddr_t cp;
{
int len;
len = strlen(cp) + 1;
if (nextstrx+len >= maxstrx) {
maxstrx += INCSTRX;
if (newstringtab) {
newstringtab = (caddr_t)realloc(newstringtab, maxstrx);
} else {
newstringtab = (caddr_t)malloc(maxstrx);
}
}
strcpy(newstringtab + nextstrx, cp);
nextstrx += len;
}